#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->comboBox_IP->addItem(GertLocalIpAddress());
    tcpserver=new QTcpServer(this);
     connect(tcpserver,&QTcpServer::newConnection,this,&MainWindow::newconnection);//收到新的连接是newConnection

}

MainWindow::~MainWindow()
{
    delete ui;
}

QString MainWindow::GertLocalIpAddress()
{
    QString hostaddress=QHostInfo::localHostName();
    QHostInfo hostinfo=QHostInfo::fromName(hostaddress);
    QList<QHostAddress> addresslist=hostinfo.addresses();
    QString localip="";
    for(int i=0;i<addresslist.size();i++)
    {
        QHostAddress tempip=addresslist.at(i);
        if(!addresslist.isEmpty())
        {
            if(tempip.protocol()==QAbstractSocket::IPv4Protocol)
            {
                localip=tempip.toString();
                break;
            }
        }
    }
    return localip;
}

void MainWindow::closeEvent(QCloseEvent *ev)
{
    if(tcpserver->isListening())
    {
        tcpserver->close();
    }
    ev->accept();
}


void MainWindow::on_pushButton_start_clicked()
{
    quint16 port=ui->spinBox_port->value();
    QString ip=ui->comboBox_IP->currentText();
    QHostAddress address(ip);
    tcpserver->listen(address,port);
    ui->plainTextEdit->appendPlainText("*******开始监听*******");
    ui->plainTextEdit->appendPlainText("****监听的地址****"+tcpserver->serverAddress().toString());
    ui->plainTextEdit->appendPlainText("****监听的端口号****"+QString::number(tcpserver->serverPort()));
    ui->pushButton_stop->setEnabled(true);
    ui->pushButton_start->setEnabled(false);


}

void MainWindow::on_pushButton_stop_clicked()
{
    if(tcpserver->isListening())
    {
        tcpserver->close();//断开监听状态
        ui->plainTextEdit->appendPlainText("服务端断开");
        ui->pushButton_start->setEnabled(true);
        ui->pushButton_stop->setEnabled(false);
    }
}

void MainWindow::on_pushButton_send_clicked()
{
     QString msg=ui->lineEdit_message->text();
     ui->lineEdit_message->clear();
     ui->plainTextEdit->appendPlainText("[out:]"+msg);
     QByteArray str=msg.toUtf8();
     str.append("\n");//TCP 是面向流的协议，不像 UDP 那样有自然的消息边界。添加 \n 可以：为接收端提供一个明确的消息结束标记,允许接收方使用 readLine() 等方法按行读取数据,  避免多个消息粘连在一起难以区分
     tcpsocket->write(str);

}

void MainWindow::newconnection()
{
    tcpsocket=tcpserver->nextPendingConnection();//接收到新连接
    connect(tcpsocket,&QTcpSocket::connected,this,&MainWindow::clientconnect);
    connect(tcpsocket,&QTcpSocket::disconnected,this,&MainWindow::clientdisconnect);
    connect(tcpsocket,&QTcpSocket::readyRead,this,&MainWindow::readdata);
}

void MainWindow::clientconnect()
{
      ui->plainTextEdit->appendPlainText("**********客户端socket连接**********");
      ui->plainTextEdit->appendPlainText("******客户端地址******"+tcpsocket->peerAddress().toString());
      ui->plainTextEdit->appendPlainText("********客户端端口号********"+QString::number(tcpsocket->peerPort()));


}

void MainWindow::clientdisconnect()
{
    ui->plainTextEdit->appendPlainText("**********客户端socket断开连接**********");
    tcpsocket->deleteLater();//取消这个套接字,***
}

void MainWindow::readdata()
{
     if(tcpsocket->canReadLine())//canReadLine() 方法只有在检测到换行符 \n 时才会返回 true,readLine() 方法会读取数据直到遇到换行符，或者达到最大限制,如果没有换行符，这些方法会一直等待，直到超时或连接关闭
     {
         ui->plainTextEdit->appendPlainText("[in:]"+tcpsocket->readLine());
     }
}
